package com.example.util;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;
import java.net.URI;
import java.util.Set;
import java.util.Queue;
import com.example.model.UrlDepth;

/**
 * URL处理工具类
 * 
 * 职责：
 * 1. 统一处理所有URL相关的操作
 * 2. 提供URL验证和过滤功能
 * 3. 管理URL的发现和去重
 * 4. 处理URL的深度控制
 * 
 * 功能模块：
 * 1. URL解析
 *    - 提取主域名
 *    - 解析URL结构
 *    - 处理特殊字符
 * 
 * 2. URL验证
 *    - 验证协议有效性
 *    - 验证域名匹配
 *    - 过滤特定路径
 *    - 排除文件类型
 * 
 * 3. URL发现
 *    - 从页面提取链接
 *    - 处理相对路径
 *    - 维护URL队列
 *    - 控制爬取深度
 * 
 * 4. URL过滤
 *    - 排除登出页面
 *    - 排除搜索页面
 *    - 排除用户页面
 *    - 排除登录页面
 * 
 * 使用方式：
 * 1. 通过Spring依赖注入使用
 * 2. 调用相应方法处理URL
 * 3. 配合爬虫服务使用
 */
@Component
public class UrlUtil {

    /**
     * 从URL提取主域名
     * @param url URL字符串
     * @return 主域名
     */
    public String extractDomain(String url) throws Exception {
        URI uri = new URI(url);
        String domain = uri.getHost();
        if (domain == null) throw new Exception("无效URL");
        return domain.startsWith("www.") ? domain.substring(4) : domain;
    }

    /**
     * 验证URL有效性
     * @param url URL字符串
     * @param allowedDomain 允许的域名
     * @return 是否有效
     */
    public boolean isValidUrl(String url, String allowedDomain) {
        try {
            URI uri = new URI(url);
            // 验证协议
            if (!uri.getScheme().matches("https?")) return false;
            
            // 验证域名
            String domain = uri.getHost();
            domain = domain.startsWith("www.") ? domain.substring(4) : domain;
            if (!domain.equals(allowedDomain)) return false;
            
            // 验证路径
            String path = uri.getPath().toLowerCase();
            
            // 排除登出、搜索、用户页面等
            if (path.contains("/logout") || 
                path.contains("/search") || 
                path.contains("/user/") ||
                path.contains("/login")) {
                return false;
            }
            
            // 排除特定文件类型
            if (path.matches(".*\\.(pdf|docx|zip|jpg|jpeg|png|gif|mp4|mp3)$")) {
                return false;
            }
            
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 从文档中发现新的URL
     * @param doc Jsoup文档对象
     * @param current 当前URL
     * @param visitedUrls 已访问的URL集合
     * @param urlQueue URL队列
     * @param allowedDomain 允许的域名
     */
    public void discoverNewUrls(Document doc, UrlDepth current,
                              Set<String> visitedUrls, Queue<UrlDepth> urlQueue,
                              String allowedDomain) {
        Elements links = doc.select("a[href]");
        for (Element link : links) {
            String newUrl = link.absUrl("href");
            if (isValidUrl(newUrl, allowedDomain) && !visitedUrls.contains(newUrl)) {
                visitedUrls.add(newUrl);
                urlQueue.add(new UrlDepth(newUrl, current.getDepth() + 1));
            }
        }
    }
} 